package cn.netuo.bumbersoll.ijk;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.AttributeSet;

import com.dueeeke.videoplayer.player.IjkVideoView;
import com.dueeeke.videoplayer.player.VideoViewManager;
import com.rooten.help.filehttp.HttpDownloadRequest;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import cn.netuo.bumbersoll.App;
import cn.netuo.bumbersoll.R;
import cn.netuo.bumbersoll.entity.VideoAd;
import cn.netuo.bumbersoll.util.BsUtil;
import lib.grasp.util.FileUtil;
import lib.grasp.util.L;
import lib.grasp.util.PathUtil;

/**
 * Created by GaQu_Dev on 2019/4/16.
 */
public class SunIjkVideoView extends IjkVideoView {

    public SunIjkVideoView(@NonNull Context context) {
        super(context);
        IS_PLAY_ON_MOBILE_NETWORK = true;
    }

    public SunIjkVideoView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        IS_PLAY_ON_MOBILE_NETWORK = true;
    }

    public SunIjkVideoView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        IS_PLAY_ON_MOBILE_NETWORK = true;
    }

    @Override
    public void onCompletion() {
        super.onCompletion();
        L.logOnly("视频播放完了");
        doPlayNext();
    }

    /** 开始播放(从播放列表中选择下一个) */
    public void doStartPlay(){
        if(mVideoController == null || isPlaying()) return;
        postDelayed(this::doPlayNext, 200);
    }

    /** 开始播放下一个 */
    public void doPlayNext(){
        setUrl(getNextVideoPath());      //设置视频地址
        startFullScreen();
        start();           //开始播放，不调用则不自动播放
        retry();

        if(mVideoController != null) ((SunController)mVideoController).doLockAll();
    }

    /** 获取下一个视频本地地址 */
    private String getNextVideoPath(){
        if(App.getApp().mVideoLoadTasks.size() == 0) return "";

        int currIndex = 0;
        for(int i = 0; i < App.getApp().mVideoLoadTasks.size(); i++){
            String key = App.getApp().mVideoLoadTasks.keyAt(i);
            VideoAd videoAd = App.getApp().mVideoLoadTasks.valueAt(i);
            String filePath = PathUtil.PATH_DOWN_OK + videoAd.name;
            if(!TextUtils.equals(mCurrentUrl, filePath)) continue;
            currIndex = i;
            break;
        }
        int nextIndex = (currIndex + 1) % App.getApp().mVideoLoadTasks.size();
        VideoAd videoAd = App.getApp().mVideoLoadTasks.valueAt(nextIndex);
        if(videoAd.url.startsWith("android.resource")) return videoAd.url;
        return PathUtil.PATH_DOWN_OK + videoAd.name;
    }

    /** 下载好的/能播放的 视频已更新 */
    public void notifyDataChanged(){
        // 重新去DB里面获取视频列表, 只查下载好的
        ArrayList<VideoAd> list = App.getApp().getTableMgr().getTbVideoAd().queryLastVideoAdByLoadState(VideoAd.LOAD_STATE_OK);
        if(list == null) return;
        if(list.size() == 0) { // 没有新的可以播放的视频
            if(App.getApp().mVideoLoadTasks.size() == 0) {  // 当前正在播放的视频也没有
                VideoAd videoAd = BsUtil.getDefaultVideo();
                list.add(videoAd);                          // 添加默认视频
            }
            else{
                doStartPlay();
                return;
            }
        }

        L.logOnly("下载完成之后, 剩:" + list.size() + "个视频可用");
        App.getApp().mVideoLoadTasks.clear();
        for(VideoAd ad : list){
            App.getApp().mVideoLoadTasks.put(ad.url, ad);
        }
        doStartPlay();
    }

    /** 停止播放 */
    public void doStopPlay(){
        postDelayed(() -> {
            stopPlayback();   // 停止播放
            release();
        }, 200);
    }


    /** [轮询数据库广告]或者[服务推送新广告(也要存db)], 将结果传入以供对比 */
    public void doCheckVideoTask(){
        ArrayList<VideoAd> listFromDB = App.getApp().getTableMgr().getTbVideoAd().queryLastVideoAdByLoadState(-1);
        if(listFromDB == null) return;
        if(listFromDB.size() == 0){ // 代表服务器要求停止播放任何视频
            App.getApp().mVideoLoadTasks.clear();
            doStopPlay();
            return;
        }

        if(App.getApp().mVideoLoadTasks == null) App.getApp().mVideoLoadTasks = new ArrayMap<>();

        if(App.getApp().mVideoLoadTasks.size() == 0){    // 原来没有下载任务
            App.getApp().mVideoLoadTasks.clear();
            for(VideoAd temp : listFromDB) App.getApp().mVideoLoadTasks.put(temp.url, temp);
            addDownTask(listFromDB); // 将新列表装入下载队列
            return;
        }

        // DB列表中的任意一项视频下载任务
        VideoAd firstVideoAdFromDB = listFromDB.get(0);

        // 当前map中的任意一项视频下载任务
        Iterator<VideoAd> iterator = App.getApp().mVideoLoadTasks.values().iterator();
        VideoAd firstVideoAdFromMap = iterator.next();

        // DB列表(任意一项)晚于Map列表, 则Map列表过期
        if(firstVideoAdFromDB.indbtime == firstVideoAdFromMap.indbtime) return; // 这里是为了防止轮询线程多次用DBlist来比对

        // 部分更新视频广告列表(有新广告来了)
        ArrayList<VideoAd>  diffList = new ArrayList<>();       // 先找到要新下载的(原来没有的视频, 正在下载的视频也认为一定会下好)
        for(VideoAd temp : listFromDB){ // 遍历新DB列表
            if(!App.getApp().mVideoLoadTasks.containsKey(temp.url)){         // 新列表相对以旧列表新增的视频
                diffList.add(temp);
            }
            else if(App.getApp().mVideoLoadTasks.containsKey(temp.url)){     // 旧列表其中有的视频要继续用
                App.getApp().mVideoLoadTasks.get(temp.url).indbtime = temp.indbtime;
//                App.getApp().getTableMgr().getTbVideoAd().updateArgValue(temp.url, VideoAd.LOAD_STATE_OK);
            }
        }

        long newTime = listFromDB.get(0).indbtime;  // 新版本的入库时间

        // 找到旧列表里面再也不用的视频
        ArrayList<VideoAd>   outDateList = new ArrayList<>();
        for(Map.Entry<String, VideoAd> entry : App.getApp().mVideoLoadTasks.entrySet()){
            String  key     = entry.getKey();
            VideoAd value   = entry.getValue();
            if(value.indbtime >= newTime) continue;
            outDateList.add(value);
        }
        for(VideoAd video : outDateList) {
            VideoAd videoAd = App.getApp().mVideoLoadTasks.remove(video.url);        // 从map列表删除
        }

        L.logOnly("比对完成之后, 剩:" + App.getApp().mVideoLoadTasks.size() + "个视频可用");
        if(App.getApp().mVideoLoadTasks.size() == 0){        // 之前广告一个都没有用了
//            doStopPlay();
            VideoAd videoAd = BsUtil.getDefaultVideo();
            App.getApp().mVideoLoadTasks.put(videoAd.name, videoAd);
            doPlayNext();
        }
        else{                                   // 至少还有一个就视频还能接着用
            doPlayNext();
        }

        for(VideoAd video : outDateList) {
            FileUtil.delFile(PathUtil.PATH_DOWN_OK +  video.name);    // 从文件里删除, 在最后删除是为了防止删除播放器正在播放的视频
        }

        addDownTask(diffList); // 将差异列表装入下载队列 原来
    }

    /** 将列表装入下载队列 */
    private void addDownTask(ArrayList<VideoAd> list){
        if(list == null || list.size() == 0) return;
        for(VideoAd temp : list){
            addTask(temp);
        }
    }

    /** 添加下载任务 */
    private void addTask(VideoAd videoAd){
        String url      = videoAd.url;
        String savePath = PathUtil.PATH_DOWN_TEMP + videoAd.name;
        File saveFile = new File(savePath);
        Map<String, String> head = new HashMap<>();
        Map<String, String> body = new HashMap<>();

        HttpDownloadRequest request = HttpDownloadRequest.createDefaultReq(url, saveFile, head, body, (SunController)mVideoController);
        App.getApp().getFileDownloadMgr().addDownWork(App.getApp().mDownLoadId, request);
    }
}
